﻿using HalconDotNet;
using Sunny.UI;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using ZRFCore.Camera;
using ZRFCore.MachineVisionAlgorithm.Controls.ZrfWindowControl.Model;
using ZRFCore.MachineVisionAlgorithm.Controls.ZrfWindowControl.Object;
using ZRFCore.MachineVisionAlgorithm.ShapeMatching;
using MultiAxisAssembly;

namespace 喷点胶机
{
    public partial class Page_2_EditShapeModel : UIPage
    {
        private ControlMaster controlMaster;
        private ShapeMatching shapeMatching;

        public Page_2_EditShapeModel(ControlMaster controlMaster)
        {
            InitializeComponent();
            this.zrf_hWindow1.Location = new System.Drawing.Point(12, 12);
            this.zrf_hWindow1.Size = new System.Drawing.Size(1167, 809);
            zrf_hWindow1.HMouseDown += Zrf_hWindow1_HMouseDown;
            this.controlMaster = controlMaster;
           
            shapeMatching = controlMaster.ShapeMatching;
        }

        public static class EditShapeMaching
        {
            public static HRegion ShapeModelCalRoi(List<IROI> rois)
            {
                try
                {
                    if (rois == null || rois.Count == 0)
                    {
                        throw new Exception("区域为空,无法计算");
                    }
                    HRegion region = GetListRoi(rois, 1);
                    HRegion ignoreRegion = GetListRoi(rois, 2);
                    return CalRois(region, ignoreRegion);
                }
                catch (Exception)
                {
                    throw;
                }
            }

            private static HRegion GetListRoi(List<IROI> rois, int groupIndex)
            {
                HOperatorSet.GenEmptyObj(out HObject hRegion);
                foreach (var roi in rois)
                {
                    if (roi.GroupIndex == groupIndex)
                    {
                        HOperatorSet.ConcatObj(hRegion, roi.GetRegion(), out HObject concat);
                        hRegion = new HRegion(concat);
                        //hRegion.ConcatObj(roi.GetRegion());
                    }
                }
                HOperatorSet.Union1(hRegion, out HObject regionResult);
                return new HRegion(regionResult);
            }

            private static HRegion CalRois(HRegion region, HRegion ignoreRegion)
            {
                return region.Difference(ignoreRegion);
            }
        }

        public override void Init()
        {
            base.Init();
            uiTrackBar1.Value = (int)(shapeMatching.AngleExtent / 2);
            uiTrackBar2.Value = (int)(shapeMatching.MinScore * 100);
            zrf_hWindow1.Rois = controlMaster.ShapeModelRois;
            zrf_hWindow1.Image = controlMaster.StandardImg;
        }

        public override void Final()
        {
            base.Final();
            if (zrf_hWindow1.Image == null || !zrf_hWindow1.Image.IsInitialized())
            {
                return;
            }
            CreateShapeMaching();
        }

        private void uiTrackBar1_ValueChanged(object sender, EventArgs e)
        {
            uiLabel1.Text = String.Format("旋转角度±{0}°", uiTrackBar1.Value);
        }

        private void uiTrackBar2_ValueChanged(object sender, EventArgs e)
        {
            uiLabel4.Text = String.Format("匹配相似度{0}%", uiTrackBar2.Value);
            shapeMatching.MinScore = (double)uiTrackBar2.Value / 100;
        }

        private void btDrawRec2_Click(object sender, EventArgs e)
        {
            if (zrf_hWindow1.Image == null || !zrf_hWindow1.Image.IsInitialized())
            {
                ShowErrorDialog("窗口内图像为空，请先抓图再编辑");
                return;
            }
            zrf_hWindow1.DrawRect2("forest green", 1);
        }

        private void btDrawCircle_Click(object sender, EventArgs e)
        {
            if (zrf_hWindow1.Image == null || !zrf_hWindow1.Image.IsInitialized())
            {
                ShowErrorDialog("窗口内图像为空，请先抓图再编辑");
                return;
            }
            zrf_hWindow1.DrawCircle("forest green", 1);
        }

        private void btDrawIgnoreRec2_Click(object sender, EventArgs e)
        {
            if (zrf_hWindow1.Image == null || !zrf_hWindow1.Image.IsInitialized())
            {
                ShowErrorDialog("窗口内图像为空，请先抓图再编辑");
                return;
            }
            zrf_hWindow1.DrawRect2("firebrick", 2);
        }

        private void btDrawIgnoreCircle_Click(object sender, EventArgs e)
        {
            if (zrf_hWindow1.Image == null || !zrf_hWindow1.Image.IsInitialized())
            {
                ShowErrorDialog("窗口内图像为空，请先抓图再编辑");
                return;
            }
            zrf_hWindow1.DrawCircle("firebrick", 2);
        }

        private void btCalRois_Click(object sender, EventArgs e)
        {
            if (zrf_hWindow1.Image == null || !zrf_hWindow1.Image.IsInitialized())
            {
                ShowErrorDialog("窗口内图像为空，请先抓图");
                return;
            }
            try
            {
                HRegion ShapeModelArea = EditShapeMaching.ShapeModelCalRoi(zrf_hWindow1.Rois);
                zrf_hWindow1.EnShowRois = false;
                zrf_hWindow1.EnShowXldPaths = false;
                zrf_hWindow1.EnShowHRegions = true;
                zrf_hWindow1.HRegions.Clear();
                zrf_hWindow1.HRegions.Add(new HRegionWithColor(ShapeModelArea, "yellow"));
                zrf_hWindow1.Repaint();
            }
            catch (Exception ee)
            {
                ShowErrorDialog(ee.Message);
            }
        }

        private void Zrf_hWindow1_HMouseDown(object sender, HMouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                zrf_hWindow1.EnShowRois = true;
                zrf_hWindow1.EnShowXldPaths = true;
                zrf_hWindow1.EnShowHRegions = false;
                zrf_hWindow1.EnShowHXLDs = false;
                zrf_hWindow1.Repaint();
            }
        }

        private void btMachingTest_Click(object sender, EventArgs e)
        {
            if (zrf_hWindow1.Image == null || !zrf_hWindow1.Image.IsInitialized())
            {
                ShowErrorDialog("窗口内图像为空，请先抓图再编辑");
                return;
            }

            try
            {
                CreateShapeMaching();
                FoundModel[] foundModels = shapeMatching.FindAllShapeModels(zrf_hWindow1.Image);
                zrf_hWindow1.HXLDs.Clear();
                foreach (var foundModel in foundModels)
                {
                    zrf_hWindow1.HXLDs.Add(new HXLDWithColor(foundModel.ModelOutXld, "green"));
                }
                zrf_hWindow1.EnShowRois = false;
                zrf_hWindow1.EnShowXldPaths = false;
                zrf_hWindow1.EnShowHXLDs = true;
                zrf_hWindow1.Repaint();
                zrf_hWindow1.DispTextOnWindow(String.Format("找到{0}个", foundModels.Length), 10, 10, "green");
                foreach (var foundModel in foundModels)
                {
                    zrf_hWindow1.DispTextOnImage(String.Format("相似度{0:N3}%", foundModel.Score * 100), foundModel.Row, foundModel.Column, "red");
                }
            }
            catch (Exception ee)
            {
                ShowErrorDialog(ee.Message);
            }
        }

        private void CreateShapeMaching()
        {
            try
            {
                int angleStart = -uiTrackBar1.Value;
                int angleExtent = uiTrackBar1.Value * 2;
                double minScore = ((double)uiTrackBar2.Value) / 100;
                HRegion ShapeModelArea = EditShapeMaching.ShapeModelCalRoi(zrf_hWindow1.Rois);
                HOperatorSet.ReduceDomain(zrf_hWindow1.Image, ShapeModelArea, out HObject imgReduce);
                shapeMatching .MinScore = minScore;
                shapeMatching.MaxOverlap = 0;
                shapeMatching.AngleStart = angleStart;
                shapeMatching.AngleExtent = angleExtent;
                shapeMatching.CreateShapeMatchModel(new HImage(imgReduce));
            }
            catch (Exception e)
            {
                ShowErrorDialog(e.Message);
            }
        }

    }
}
